#include "../include/wrap.h"

int main(int argc, char **argv)
{
	int i, maxi, maxfd, listenfd, connfd, sockfd;
	
	int nready;
	int client[FD_SETSIZE];/* Number of client*/
	ssize_t n;

	fd_set rset, allset;

	char buf[MAXLINE];
	char str[INET_ADDRSTRLEN];

	socklen_t cliaddr_len;

	/* Address structure information */
	struct sockaddr_in	cliaddr, servaddr;

	listenfd = Socket(AF_INET, SOCK_STREAM, 0);

	/* Initiaalize address */
	bzero(&servaddr, sizeof(servaddr));
	servaddr.sin_family      = AF_INET;
	servaddr.sin_addr.s_addr = htonl(INADDR_ANY);
	servaddr.sin_port        = htons(SERV_PORT);

	/* Bind socket to address */
	Bind(listenfd, (struct sockaddr *)&servaddr, sizeof(servaddr));

	/* Start listen */
	Listen(listenfd, 20);

	maxfd = listenfd;		/* initialize */
	maxi = -1;			

	for (i = 0; i < FD_SETSIZE; i++)
		client[i] = -1;	/* -1 indicates available entry */

	FD_ZERO(&allset);
	FD_SET(listenfd, &allset);

	for (;;) {
		rset = allset;	/* structure assignment */

		nready = select(maxfd+1, &rset, NULL, NULL, NULL);

		if (nready < 0)
			perr_exit("select error");

		if (FD_ISSET(listenfd, &rset)) 
		{ 
			/* new client connection */
			cliaddr_len = sizeof(cliaddr);
			connfd = Accept(listenfd, (struct sockaddr *)&cliaddr, &cliaddr_len);

			printf("received from %s at PORT %d\n",
			       inet_ntop(AF_INET, &cliaddr.sin_addr, str, sizeof(str)),
			       ntohs(cliaddr.sin_port));

			for (i = 0; i < FD_SETSIZE; i++)
				if (client[i] < 0) 
				{
					client[i] = connfd; 
					/* save descriptor */
					break;
				}
			if (i == FD_SETSIZE) 
			{
				fputs("too many clients\n", stderr);
				exit(1);
			}

			FD_SET(connfd, &allset);	/* add new descriptor to set */
			
			if (connfd > maxfd)
				maxfd = connfd; 	/* for select */
			if (i > maxi)
				maxi = i;		/* max index in client[] array */

			if (--nready == 0)
				continue;		/* no more readable descriptors */
		}

		for (i = 0; i <= maxi; i++) 
		{	
			/* check all clients for data */
			if ( (sockfd = client[i]) < 0)
				continue;
			if (FD_ISSET(sockfd, &rset)) 
			{
				fb_info my_fb;
				int length = (my_fb.w * my_fb.h * my_fb.bpp) / 8;
				if(init(&my_fb) < 0)
				{
					printf("Initialize fialed\n");
					return 1;
				}

				#if 1
				fb_chess_map(my_fb, 280, 40, 720, 0x00000000);
				save_chess(my_fb);	
				#endif

				fb_chess_play(my_fb);	
				munmap(my_fb.fbmem, length);
				if ( (n = Read(sockfd, buf, MAXLINE)) == 0) 
				{
					/* connection closed by client */
					Close(sockfd);
					FD_CLR(sockfd, &allset);
					client[i] = -1;
				} 
				else 
				{
					int j;
					for (j = 0; j < n; j++)
						buf[j] = toupper(buf[j]);
					Write(sockfd, buf, n);
				}

				if (--nready == 0)
					break;	/* no more readable descriptors */
			}
		}
	}
}
